/*--------------------------------------------------------------------------------------*\
**
** adv_ferry.cpp
**
** Heroes IV
** Copyright 2000, The 3DO Company
**
\*--------------------------------------------------------------------------------------*/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "adv_ferry.h"

#include "adv_ferry_vector.h"
#include "adv_object_type.h"
#include "adventure_ai.h"
#include "adventure_frame.h"
#include "adventure_map.h"
#include "adventure_sounds.h"
#include "adventure_path_finder.h"
#include "adv_object_type.h"
#include "adv_actor_model.h"
#include "army.h"
#include "bitmap_group_cache.h"
#include "dialog_teleporter_entrance.h"
#include "gateway_selection.h"
#include "music.h"
#include "object_registration.h"
#include "player.h"
#include "simple_dialog.h"
#include "stationary_adventure_object.h"

// --------------------------------------------------------------------------
// Unnamed namespace
// --------------------------------------------------------------------------

namespace
{
	t_object_registration< t_adv_ferry > g_adv_ferry_registration( k_adv_object_ferry );
} // Unnamed namespace

t_adv_ferry::t_adv_ferry (  std::string const& source )
          : t_gateway_base( source )
{
}

void t_adv_ferry::activate_trigger( t_army* army, t_adv_map_point const& point, 
		                           t_direction direction, t_adventure_frame* frame )
{
    // Get all ferrys.
	t_adv_ferry_const_vector		ferry_list = m_map->get_ferries_in_group( this );
    t_adv_ferry_const_vector        possible_ferries;
    t_level_map_point_2d_list       ferry_points;
    std::vector<std::string>        ferry_names;
    int                             selected_ferry;
    int                             i;

    for (i=0; i < ferry_list.size(); i++)
    {
	    if ( ferry_list[i].get() != this )
        {
    	    ferry_points.push_back ( ferry_list[i]->get_position() );
            ferry_names.push_back ( ferry_list[i]->get_name() );

            // Create a list of possible ferrys.
            possible_ferries.push_back (ferry_list[i]);
        }
    }

	if (army->get_owner()->is_computer()) 
	{
		t_adventure_path const& path = m_map->get_ai().get_current_path();
		t_adv_map_point dest_point = point + get_direction_offset( direction );

		t_gateway_base const* base = ai_select_gateway_exit( path, ferry_list, this, army, dest_point );
		if (base)
			teleport_army ( *base, army, frame );
		return;
	}	

	t_sound_cache music = get_music_playing();
	stop_music();
	get_dialog_sound( k_dialog_sound_shipyard )->play( get_sound_volume() );

	if ( possible_ferries.empty() )
	{
		ok_dialog( get_text( "denied" ), true, get_text("Name") );
		play_music( music );
		return;
	}

    // Show selection dialog window (if more than 1 - else, dialog just returns).
	t_counted_ptr<t_dialog_teleporter_entrance> dialog_ptr;

	dialog_ptr = new t_dialog_teleporter_entrance( frame );
	dialog_ptr->init_dialog( frame, ferry_points, ferry_names, 0, get_text("Name"), get_text ("Initial") );
	dialog_ptr->run_modal();
	play_music( music );

    selected_ferry = (dialog_ptr->get_selected_exit());

    // Refused
    if (selected_ferry == -1)
        return;

    /*
    ** Teleport army.
    */
    teleport_army ( *possible_ferries[ selected_ferry ], army, frame );
}

void t_adv_ferry::place( t_adventure_map& map, t_adv_map_point const& point )
{
    t_gateway_base::place( map, point );
    
    // Add ferry.
    map.add_ferry ( this );
}

void t_adv_ferry::destroy()
{
	t_gateway_base::destroy();

	m_map->remove_ferry( this );
}

void t_adv_ferry::pathing_destination_query( t_adventure_path_point const& source,
										     t_adventure_path_finder & path_finder ) const
{
	t_adv_ferry_const_vector	ferry_list = m_map->get_ferries_in_group( this );

	t_adv_ferry_const_vector::iterator it;

	for ( it = ferry_list.begin(); it != ferry_list.end(); it++ )
	{
	    if ( this != it->get() )
		{
		    t_adv_map_point ferry_exit;
		    if ( (*it)->find_adjacent_space( ferry_exit, *path_finder.get_army() ) )
			{
				ferry_exit.on_bridge = false;

				path_finder.push( ferry_exit, source, 0 );
			}
		}
	}
}

